package com.joejag.mavenstats.client.views.sidebar.children;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.joejag.mavenstats.client.MavenStats;
import com.joejag.mavenstats.client.dto.ProjectDTO;
import com.joejag.mavenstats.client.service.ProjectsService;
import com.joejag.mavenstats.client.service.ProjectsServiceAsync;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Projects extends Composite implements TreeListener
{
  private Tree tree;

  public Projects(final Images images)
  {
    tree = new Tree(images);
    tree.addTreeListener(this);

    refreshTree(images);

    initWidget(tree);
  }

  public void refreshTree(final Images images)
  {
    final List currentlyOpenedBranches = getCurrentlyOpenedBranches();

    ProjectsServiceAsync serviceAsync = ProjectsService.App.getInstance();
    serviceAsync.getProjects(new AsyncCallback()
    {
      public void onFailure(Throwable throwable)
      {
      }

      public void onSuccess(Object o)
      {
        tree.clear();
        Map map = (Map) o;
        Iterator iterator = map.keySet().iterator();
        while (iterator.hasNext())
        {
          String teamName = iterator.next().toString();
          TreeItem root = new TreeItem(imageItemHTML(images.team(), teamName));
          tree.addItem(root);

          List projects = (List) map.get(teamName);
          for (int i = 0; i < projects.size(); i++)
            addImageItem(root, projects.get(i), images.project());

          if (currentlyOpenedBranches.contains(teamName))
            root.setState(true);
        }
      }
    });
  }

  private List getCurrentlyOpenedBranches()
  {
    List openBranches = new ArrayList();

    Iterator iterator = tree.treeItemIterator();
    while (iterator.hasNext())
    {
      TreeItem treeItem = (TreeItem) iterator.next();
      if (treeItem.getState())
        openBranches.add(treeItem.getText());
    }

    return openBranches;
  }

  private TreeItem addImageItem(TreeItem root, Object projectObj, AbstractImagePrototype imageProto)
  {
    ProjectDTO project = (ProjectDTO) projectObj;

    TreeItem item = new ProjectTreeItem(imageItemHTML(imageProto, project.projectName), project);
    root.addItem(item);
    return item;
  }

  private String imageItemHTML(AbstractImagePrototype imageProto, String title)
  {
    return "<span>" + imageProto.getHTML() + title + "</span>";
  }

  public void onTreeItemSelected(TreeItem treeItem)
  {
    if (treeItem.getChildCount() == 0)
      MavenStats.instance().displayProject(
              ((ProjectTreeItem) treeItem).project);
  }

  public void onTreeItemStateChanged(TreeItem treeItem)
  {
  }

  public interface Images extends ImageBundle, TreeImages
  {
    /**
     * @gwt.resource com/joejag/mavenstats/client/images/plugins/asterisk_yellow.png
     */
    AbstractImagePrototype team();

    /**
     * @gwt.resource com/joejag/mavenstats/client/images/plugins/plugin.png
     */
    AbstractImagePrototype project();
  }
}
